package com.firemoss.atonement.metadata.inspectors.entity
{
	import com.firemoss.atonement.metadata.EntityMetadata;
	import com.firemoss.atonement.metadata.IMetadataBuilder;
	
	import flash.utils.Dictionary;
	
	import org.as3commons.reflect.Field;
	import org.as3commons.reflect.MetaData;
	import org.as3commons.reflect.MetaDataArgument;
	import org.as3commons.reflect.MetadataUtils;
	import org.as3commons.reflect.Type;
	
	public class DefaultEntityInspector implements IEntityInspector
	{
		private var _metadataBuilder : IMetadataBuilder
		
		public function DefaultEntityInspector()
		{
		}
		
		public function inspect(metadataBuilder:IMetadataBuilder, clazz:Class):EntityMetadata
		{
			var type:Type = Type.forClass( clazz )
			var md:EntityMetadata = new EntityMetadata()
				
			determineIdentifier( clazz, type, md );
			determineName( clazz, type, md );

			return md;
		}
		
		protected function determineIdentifier( clazz:Class, type:Type, md:EntityMetadata ) : void
		{
			var field:Field
			
			// First, honor annotation
			for each ( field in type.fields )
			{
				for each ( var fieldMd : MetaData in field.metaData )
				{
					if ( fieldMd.name == "Id" )
					{
						md.idPropertyName = field.name
						return
					}
				}
			}
			
			// Second, look for something named "id"
			for each ( field in type.fields )
			{
				if ( field.name.toUpperCase() == "ID" )
				{
					md.idPropertyName = field.name
					return
				}
			}

			// Third, look for something named "typeNameId"
			var typeNameId : String = (type.name + "id").toUpperCase();
			
			for each ( field in type.fields )
			{
				if ( field.name.toUpperCase() == typeNameId )
				{
					md.idPropertyName = field.name
					return
				}
			}
		}
		
		protected function determineName( clazz:Class, type:Type, md:EntityMetadata ) : void
		{
			// Not sure how reflect sets "name," so we'll trust fullName...
			var splitName : Array = type.fullName.split( "::" );
			md.entityName = splitName[ splitName.length - 1 ];
			
			for each ( var meta : MetaData in type.metaData )
			{
				if ( meta.name == "Entity" )
				{
					for each ( var arg : MetaDataArgument in meta.arguments )
					{
						if ( arg.key == "name" && arg.value != null && arg.value.length > 0 )
						{
							md.entityName = arg.value;
							return;
						}
					}
				}
			}
		}
		
	}
}